package com.project.service;

import com.project.dao.UserMapper;
import com.project.entity.User;
import com.project.service.base.BaseService;
import com.project.service.base.CrpData.CrypDataHelper;
import com.project.service.base.PasswordHelper;
import com.project.service.cryptolib.CryptoApp;
import com.project.utils.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by TAO on 2015/10/1.
 */

//让checked例外也回滚
@Transactional(rollbackFor = Exception.class)
@Service
public class UserServiceImpl extends BaseService implements UserService {

    @Autowired
    private PasswordHelper passwordHelper;

    @Autowired
    private CrypDataHelper crypDataHelper;


    private static UserMapper userMapper = null;

    public void setMapper() {
        if (userMapper == null)
            userMapper = sqlSessionTemplate.getMapper(UserMapper.class);//1.获取相关mapper
    }

    /**
     * author: WheelChen
     * date: 2017/6/26
     * function: 创建用户
     *
     * @param user
     * @return
     */
    public int createUser(User user) throws Exception {
        setMapper();
        //加密密码
        passwordHelper.encryptPassword(user);
        //加密敏感信息
        crypDataHelper.encryptUser(user);
        return userMapper.insertSelective(user);
    }

    /**
     * author: WheelChen
     * date: 2017/6/26
     * function: 更新用户信息
     *
     * @param user
     * @return
     */
    @Override
    public int updateUser(User user) throws Exception {
        setMapper();
        //加密密码,需作判断，密码未改变则无需加密
        User oldUser = findOneAllByUserID(user.getId());
        if (user.getPassword() != null && !user.getPassword().isEmpty() && !oldUser.getPassword().equals(user.getPassword()))//与原密码不相同，则加密
            passwordHelper.encryptPassword(user);
        //加密敏感信息
        crypDataHelper.encryptUser(user);
        return userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * author: WheelChen
     * date: 2017/6/26
     * function: 通过username查找用户
     *
     * @param username
     * @return
     */
    @Override
    public User findByUserName(String username) throws Exception {
        setMapper();
        User user = userMapper.selectByUserName(username);
        crypDataHelper.decUser(user);
        return user;
    }

    /**
     * author: WheelChen
     * date: 2017/6/26
     * function: 验证密码是否正确
     *
     * @param sessionUser 当前user
     * @param password    被验证密码
     * @return
     */
    @Override
    public Boolean validatePassword(User sessionUser, String password) {
        try {
            String oldPassword = Util.bytesToHexString(CryptoApp.PwdTransValue(password.getBytes(), Util.hexStringToBytes(sessionUser.getSalt())));
            return oldPassword.equals(sessionUser.getPassword());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Todo 如何做成事务 批量生成一旦发生失败全部回滚
     * author: WheelChen
     * date: 2017/7/21
     * function: 批量创建用户
     *
     * @param users
     * @return 失败数量
     */
    @Override
    public int addUserBatch(List<User> users) throws Exception {
        int errorNum = 0;//失败数量
        for (int i = 0; i < users.size(); i++) {
            if (createUser(users.get(i)) > 0) {
                errorNum++;
            }
        }
        return errorNum;
    }

    /**
     * 查找用户（不过滤用户名密码）
     *
     * @param userId
     * @return
     */
    @Override
    public User findOneAllByUserID(Integer userId) throws Exception {
        setMapper();
        User user = userMapper.selectByPrimaryKey(userId);
        //解密敏感信息
        crypDataHelper.decUser(user);
        return user;
    }

    @Override
    public User findOneByUserID(Integer userId) throws Exception {
        setMapper();
        User user = userMapper.selectByPrimaryKey(userId);
        //解密敏感信息
        crypDataHelper.decUser(user);
        filterSensitiveInfo(user);
        return user;
    }

    /**
     * author: WheelChen
     * date: 2017/8/8
     * function: 根据userId查找未加密信息
     *
     * @param userId
     * @return
     */
    @Override
    public User findByUserIdUnDecry(Integer userId) {
        setMapper();
        return userMapper.selectByPrimaryKey(userId);
    }

    /**
     * author: WheelChen
     * date: 2017/8/9
     * function: 查询用户信息且不解密
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public User findByUserIdUnDecryAndFileterSensitive(Integer userId) {
        User user = findByUserIdUnDecry(userId);
        filterSensitiveInfo(user);
        return user;
    }

    /**
     * author: WheelChen
     * date: 2017/8/8
     * function: 检查手机号码是否存在
     *
     * @param mobilephone 手机号码
     * @return true - 存在 false - 不存在
     */
    @Override
    public Boolean checkMobilePhoneIsExist(String mobilephone) {
        setMapper();
        return userMapper.checkMobilePhoneIsExist(mobilephone) != 0;
    }

    /**
     * author: WheelChen
     * date: 2017/8/8
     * function: 检查用户名是否存在
     *
     * @param username 用户名
     * @return true - 存在 false - 不存在
     */
    @Override
    public Boolean checkUsernameIsExist(String username) {
        setMapper();
        return userMapper.checkUsernameIsExist(username) != 0;
    }

    /**
     * author: WheelChen
     * date: 2017/8/9
     * function: 根据id删除字段
     *
     * @param id
     * @return
     */
    @Override
    public int removeOneById(Integer id) {
        setMapper();
        return userMapper.deleteByPrimaryKey(id);
    }

    /**
     * author: WheelChen
     * date: 2017/9/19
     * function: 根据ids批量删除
     *
     * @param idList
     * @return
     */
    @Override
    public int removeBatchByIdList(List idList) {
        setMapper();
        return userMapper.deleteBatchByIdList(idList);
    }

    @Override
    public List<User> findAll(User user) {
        setMapper();
        return userMapper.selectAll(user);
    }

}
